import { Account } from './../domain/models/account';
import { ApiDataContext } from './../domain/apiDataContext';
import * as md5 from 'md5';
import { Guid } from '../common/utils/guid';
import { ServiceException } from "../common/excpetion";
import { BaseService, QueryParamsBase } from "./baseService";
import { IQueryObject } from "tiny-entity2/queryObject";
import { Transaction } from "tiny-entity2";
import Enumerable = require("linq");
import { User } from '../domain/models/user';
import { Token } from '../domain/models/token';

export class AuthenService extends BaseService {
    private tokenWhiteList: string[] = [
        'bd5ac36a4fc5ee1d755793acad5e7d7c'
    ];
    // async GetAccountByUsername(username: string, storeId?: string) {
    //     // let ctx = new ApiDataContext();
    //     // let q = ctx.Account as IQueryObject<Account>;
    //     // if (storeId) {
    //     //     q = q.Where(x => x.storeId == storeId || x.storeId == 'global', { storeId });
    //     // }
    //     // return q.Where(x => x.username == username, { username }).First();
    // }
    async QueryAccount(params: AccountQueryParams) {
        let ctx = new ApiDataContext();
        let q = ctx.Account as IQueryObject<Account>;
        if (params) {
            if (params.username) {
                q = q.Where(x => x.username == $args1, { $args1: params.username });
            }
        }

    }
    // async GetAccountById(id: string) {
    //     let ctx = new ApiDataContext();
    //     return ctx.Account.First(x => x.id == id, { id });
    // }

    // CreateAccount(account: Account): Promise<Account>;
    // CreateAccount(account: Account, ctx: ApiDataContext): Promise<Account>;
    // async CreateAccount(account: Account, ctx?: ApiDataContext) {
    //     // ctx || (ctx = new ApiDataContext());
    //     // return Transaction(ctx, async (ctx) => {
    //     //     let has = await ctx.Account.Any(x => x.username == $args1 && (x.storeId == $args2), { $args1: account.username, $args2: account.storeId });
    //     //     if (has) throw new ServiceException(`账号【${account.username}】已经存在!`);

    //     //     let a = new Account();
    //     //     a.ConverToEntity(account);
    //     //     a.id = Guid.GetGuid();

    //     //     return await ctx.Create(a);
    //     // });

    //     return null;
    // }

    // async UpdateAccount(account: Account, ctx?: ApiDataContext) {
    //     ctx || (ctx = new ApiDataContext());
    //     return Transaction(new ApiDataContext(), async (ctx) => {
    //         if (!account.id) throw new ServiceException(`没有传入账号id!`);

    //         let a = await ctx.Account.First(x => x.id == $args1, { $args1: account.id });
    //         if (!a) throw new ServiceException(`账号【${account.username}】不存在!`);

    //         a.ConverToEntity(account);
    //         let exclude = ['username', 'storeId'];
    //         if (!a.password) exclude.push('password');

    //         return ctx.Update(a, exclude);
    //     });
    // }

    async SaveLoginToken(account: Account, ip: string) {
        let tokenValue;
        return Transaction(new ApiDataContext(), async (ctx) => {
            tokenValue = md5(account.username + account.password);
            let token = await ctx.Token.First(x => x.value == $args1, { $args1: tokenValue });

            if (!token) {
                token = new Token();
                token.id = Guid.GetGuid();
                token.value = tokenValue;
                token.createTime = new Date().getTime();
                token.accountId = account.id;
                token.ip = ip;
                token = await ctx.Create(token);
            }
            return token;
        });
    }

    // async RemoveToken(tokenValue: string) {
    //     return Transaction(new ApiDataContext(), async (ctx) => {
    //         let token = await this.GetToken(tokenValue);
    //         if (token) {
    //             ctx.Delete(token);
    //         }
    //     });
    // }

    async GetToken(tokenValue: string) {
        let ctx = new ApiDataContext();
        if (this.tokenWhiteList.findIndex(x => x === tokenValue) > -1) return new Token();
        return ctx.Token.First(x => x.value == $args1, { $args1: tokenValue });
    }

    // QueryRole(p: RoleQueryParams) {
    //     let ctx = new ApiDataContext();
    //     let q = ctx.Roles as IQueryObject<Roles>;
    //     if (p) {
    //         if (p.storeId) {
    //             q = q.Where(x => x.storeId == $args1 || x.storeId == 'global', { $args1: p.storeId });
    //         }
    //         if (p.roleName) {
    //             q = q.Where(x => x.name == $args1, { $args1: p.roleName });
    //         }
    //     }
    //     return q.OrderByDesc(x => x.storeId).ToList();
    // }

    // async GetRolesByAccountId(accountId: string) {
    //     let ctx = new ApiDataContext();
    //     return await ctx.AccountRoles.Where(x => x.accountId == $args1, { $args1: accountId }).ToList();
    // }

    // async GetRoleInfo(roleId: string) {
    //     let ctx = new ApiDataContext();
    //     let list = await ctx.Roles
    //         .Join(ctx.AccountRoles).On((m, f) => m.id == f.roleId)
    //         .Where(x => x.id == roleId, { roleId })
    //         .ToList();

    //     return list.length > 0 ? list[0] : null;
    // }

    // /**
    //  * 添加角色信息
    //  * 
    //  * @param {Roles} role 
    //  * @returns 
    //  * @memberof AuthenService
    //  */
    // async CreateRole(role: Roles) {
    //     return Transaction(new ApiDataContext(), async (ctx) => {
    //         let has = await ctx.Roles.Any(x => x.name == $args1 && x.storeId == $args2, { $args1: role.name, $args2: role.storeId });
    //         if (has) throw new ServiceException(`角色[${role.name}]已经存在！`);
    //         let r = new Roles();
    //         r.ConverToEntity(role);
    //         r.id = Guid.GetGuid();

    //         return ctx.Create(r);
    //     });
    // }

    // UpdateRole(role: Roles) {
    //     return Transaction(new ApiDataContext(), async (ctx) => {
    //         let r = new Roles();
    //         r.name = role.name;
    //         r.isInneral = role.isInneral;

    //         return ctx.Update(r);
    //     });
    // }

    // async DeleteRole(roleId: string) {
    //     return Transaction(new ApiDataContext(), async (ctx) => {
    //         let role = await ctx.Roles.First(x => x.id == roleId, { roleId });
    //         if (!role) {
    //             throw new ServiceException(`角色已经删除！`);
    //         }
    //         return ctx.Delete(role);
    //     });
    // }

    // async CreateAccountRoles(accountRoles: AccountRoles, ctx?: ApiDataContext) {
    //     ctx || (ctx = new ApiDataContext());
    //     return Transaction(ctx, async (ctx) => {
    //         let role = await ctx.Roles.First(x => x.id == $args1, { $args1: accountRoles.roleId });
    //         if (!role) throw new ServiceException('角色不存在！');

    //         let ar = new AccountRoles();
    //         ar.ConverToEntity(accountRoles);
    //         ar.id = Guid.GetGuid();
    //         ar.roleName = role.name;

    //         return ctx.Create(ar);
    //     });
    // }

    // async DeleteAccount(accountId: string, ctx?: ApiDataContext) {
    //     ctx || (ctx = new ApiDataContext());
    //     return Transaction(ctx, async (ctx) => {
    //         return ctx.Delete<Account>(x => x.id == $args1, ctx.Account, { $args1: accountId });
    //     });
    // }

    // async DeleteAccountRoles(accountId: string, ctx?: ApiDataContext) {
    //     ctx || (ctx = new ApiDataContext());
    //     return Transaction(ctx, async (ctx) => {
    //         return ctx.Delete<AccountRoles>(x => x.accountId == accountId && x.storeId != 'global', ctx.AccountRoles, { accountId });
    //     });
    // }

    // async DeleteAccountRolesByRoles(roleId: string, storeId: string, ctx?: ApiDataContext) {
    //     ctx || (ctx = new ApiDataContext());
    //     return Transaction(ctx, async (ctx) => {
    //         return ctx.Delete<AccountRoles>(x => x.roleId == $args1 && x.storeId == $args2, ctx.AccountRoles, { $args1: roleId, $args2: storeId });
    //     });
    // }

    // async CreatePowerConfig(powerConfig: PowerConfig, ctx?: ApiDataContext) {
    //     ctx || (ctx = new ApiDataContext());
    //     return Transaction(ctx, async (ctx) => {
    //         return ctx.Create(powerConfig);
    //     });
    // }

    // async DeletePowerConfigByObject(objectId: string, ctx?: ApiDataContext) {
    //     ctx || (ctx = new ApiDataContext());
    //     return Transaction(ctx, async (ctx) => {
    //         return ctx.Delete<PowerConfig>(x => x.objectId == $args1, ctx.PowerConfig, { $args1: objectId });
    //     })
    // }

    // async DeletePowerConfigById(id: string, ctx?: ApiDataContext) {
    //     ctx || (ctx = new ApiDataContext());
    //     return Transaction(ctx, async (ctx) => {
    //         return ctx.Delete<PowerConfig>(x => x.id == $args1, ctx.PowerConfig, { $args1: id });
    //     })
    // }

    // QueryPowerConfigs(params) {
    //     let ctx = new ApiDataContext();
    //     let q = ctx.PowerConfig as IQueryObject<PowerConfig>;
    //     if (params) {
    //         if (params.objectId) {
    //             q = q.Where(x => x.objectId == $args1, { $args1: params.objectId })
    //         }
    //         if (params.storeId) {
    //             q = q.Where(x => x.storeId == $args1  || x.storeId == 'global', { $args1: params.storeId })
    //         }
    //     }

    //     return q.ToList();
    // }

    // GetPowerConfigById(id: string) {
    //     let ctx = new ApiDataContext();
    //     return ctx.PowerConfig.First(x => x.id == $args1, { $args1: id });
    // }

    // async GetPowerConfigsByAccountId(accountId: string) {
    //     let ctx = new ApiDataContext();
    //     let acrs = await ctx.AccountRoles.Where(x => x.accountId == $args1, { $args1: accountId }).ToList();
    //     let result: PowerConfig[] = [];
    //     for (let item of acrs) {
    //         let list = await ctx.PowerConfig.Where(x => x.objectId == $args1, { $args1: item.roleId }).ToList();
    //         result = result.concat(list);
    //     }

    //     return Enumerable.from(result).distinct(x => x.id).toArray();
    // }
}

export interface RoleQueryParams extends QueryParamsBase {
    roleName?: string;
}
export interface AccountQueryParams extends QueryParamsBase {
    username?: string;
    phone?: string;
}
export interface PowerConfigQueryParams extends QueryParamsBase {
    objectId?: string;
}
